//author: Jevgeni Krutov
//author: Sri Harsha Chilakapati
//fog implementation based on example from
//http://www.ozone3d.net/tutorials/glsl_fog/p04.php

varying vec4 vColor;
varying vec3 vPosition;
varying vec3 vNormal;

uniform vec3 lightPos;
uniform mat4 view;

const vec3 lightColor = vec3(1.0, 1.0, 1.0);
const float lightIntensity = 2.0;
const float ambientCoefficient = 0.05;
const float shininess = 128.0;

uniform int filter; //0 no filter, 1 green, -1 red, 2 gray
uniform float filterTransition; //0 no transition, 1 - green, -1 red

void main()
{
    vec3 surfaceToLight = normalize(vec3(view * vec4(lightPos, 1.0)) - vPosition);
    vec3 ambient = ambientCoefficient * vColor.rgb * lightIntensity;
    float diffuseCoefficient = max(0.0, dot(vNormal, surfaceToLight));
    vec3 diffuse = diffuseCoefficient * vColor.rgb * lightIntensity;
    float specularCoefficient = 0.0;
    if(diffuseCoefficient > 0.0) {
        specularCoefficient = pow(max(0.0, dot(surfaceToLight, reflect(-surfaceToLight, vNormal))), shininess);
    }
    vec3 specular = specularCoefficient * vec3(1.0, 1.0, 1.0) * lightIntensity;
    
    vec4 result = vColor + vec4(ambient, 1.0) + vec4(diffuse, 1.0) * vec4(lightColor, 1.0) + vec4(specular, 1.0);
    
    //---FOG---
    
    vec4 fog = vec4(0.46, 0.82, 0.93, 1.0);
    float fogDensity = 0.05;
	const float LOG2 = 1.442695;
	float fogFactor = 1 - exp2(-fogDensity * fogDensity * vPosition.z * vPosition.z * LOG2);
	fogFactor = clamp(fogFactor, 0.0, 1.0);
	
	result = mix(result, fog, fogFactor);    
    
    //---FILTERING---
    
    vec4 red = vec4(1.0, 0.0, 0.0, 1.0);
    vec4 green = vec4(0.0, 1.0, 0.0, 1.0);
    vec4 white = vec4(1.0, 1.0, 1.0, 1.0);
        
    if(filter == 0) {
    	//no filtering, but transition may be present
    	
    	if(filterTransition > 0f) {//green transition
    		result = mix(result, green, 0.3*abs(filterTransition));
    	}
	    if(filterTransition < 0f) {//red transition
	    	result = mix(result, red, 0.3*abs(filterTransition));
	    }
	    if(filterTransition > 0.9f || filterTransition < -0.9f) {
	    	result = mix(result, white, 0.7*pow(filterTransition, 2f));
	    }
	    gl_FragColor = result;
	    
	} else if(filter == 1) {
		//green filtering
		gl_FragColor = mix(result, green, 0.3);
	} else if(filter == -1) {
		//red filtering
		gl_FragColor = mix(result, red, 0.3);
	} else if(filter == 2) {
		//gray filter
		float mono = (result.x + result.y + result.z) / 3;
		gl_FragColor = vec4(mono, mono, mono, 1.0);
	}
}